import requests
import time
from django.conf import settings
from django.core.cache import cache

class WeChatAPI:
    """
    微信API工具类
    """
    
    @staticmethod
    def get_access_token():
        """
        获取微信接口调用凭证 access_token
        微信官方文档 https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-access-token/getAccessToken.html
        """
        # 先从缓存中获取
        cached_token = cache.get('wechat_access_token')
        if cached_token:
            return cached_token
        
        # 缓存中没有，重新获取
        url = f'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={settings.WECHAT_APPID}&secret={settings.WECHAT_SECRET}'
        
        try:
            response = requests.get(url)
            data = response.json()
            print("get_access_token: ")
            print(data)
            """
            返回数据示例
            {
                {'access_token': '97_pKDMgAtqeMrd9IiCskCLNa4jxCtcq5cfJ3XzFPwpOEmb04ZqcxpNGZedSoxZroBqLoYDHA1APzfaH8VaMIAf1AGo1liozxgp0q5hhJJEEIIL5swKvFEKmfx-Jv0YZJfAIAUVF',
                'expires_in': 7200}
            }
            """
            
            if 'access_token' in data:
                access_token = data['access_token']
                # token有效期为7200s
                expires_in = data.get('expires_in', 7200) - 300  # 提前5分钟过期
                
                # 缓存 access_token
                cache.set('wechat_access_token', access_token, expires_in)
                # print("access_token: " + access_token)
                
                return access_token
            else:
                print(f"获取 access_token 失败: {data}")
                return None
                
        except Exception as e:
            print(f"获取 access_token 异常: {str(e)}")
            return None
    
    @staticmethod
    def send_subscribe_message(openid, template_id, data, page=None):
        """
        发送订阅消息
        微信官方文档 https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-message-management/subscribe-message/sendMessage.html
        
        :param openid: 用户openid
        :param template_id: 模板ID
        :param data: 模板数据，格式参考微信文档
        :param page: 跳转页面路径（可选）
        :return: 发送结果
        """
        access_token = WeChatAPI.get_access_token()
        if not access_token:
            return {'errcode': -1, 'errmsg': '获取access_token失败'}
        
        url = f'https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token={access_token}'
        
        payload = {
            'touser': openid,
            'template_id': template_id,
            'data': data,
            'miniprogram_state': 'developer'  # 开发版
        }
        
        if page:
            payload['page'] = page
        
        try:
            response = requests.post(url, json=payload)
            result = response.json()
            
            # 如果 access_token 过期，清除缓存并重试一次
            # 40001 = 获取 access_token 时 AppSecret 错误，或者 access_token 无效
            if result.get('errcode') == 40001:
                cache.delete('wechat_access_token')
                access_token = WeChatAPI.get_access_token()
                if access_token:
                    print("access_token is valid")
                    url = f'https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token={access_token}'
                    response = requests.post(url, json=payload)
                    result = response.json()
            
            return result
            
        except Exception as e:
            return {'errcode': -1, 'errmsg': f'发送消息异常: {str(e)}'}